import json
from datetime import datetime, date, time
from common.timeutil import get_interval_end_pair
from datetime import timedelta
from django.conf import settings
from common.mg_core.mg import get_report_template, insert_or_update, MONGODB
from common.es_core.report_creator import UserReportCreator


def _get_graph_report_mongodb_group_by_query_dct(target_event, chn_list=None):
    group_by_query_dct = {'$group': {'_id': "$hour"}}
    group_by_template = {
        'recharge': {"key": "${param}recharge_price.sum", "multiple": settings.PLATFORM_AMOUNT_ADJUST_RATE},
        'withdraw': {"key": "${param}withdraw_price.sum", "multiple": settings.PLATFORM_AMOUNT_ADJUST_RATE},
        'bet': {"key": '%"$subtract": [%"$add": [%"$ifNull": ["${param}cp_lottery_price.sum", 0]#, '
                       '%"$ifNull": ["${param}cp_game_price.sum", 0]#]#,'
                       '%"$ifNull": ["${param}cp_lottery_refund.sum", 0]#]#',
                "multiple": settings.PLATFORM_AMOUNT_ADJUST_RATE},
        'profit': {"key": '%"$add": [%"$ifNull": ["${param}cp_lottery_profit.sum", 0]#, '
                          '%"$ifNull": ["${param}cp_game_profit.sum", 0]#]#',
                   "multiple": settings.PLATFORM_AMOUNT_ADJUST_RATE},
        'active': {'key': "${param}uv"},
        'register': {'key': "${param}uv"},
        'bind': {'key': "${param}uv"},
        'recharge_user': {'key': "${param}uv"}
    }
    assert target_event in group_by_template
    key, multiple_rate = group_by_template[target_event]['key'], group_by_template[target_event].get('multiple')
    if chn_list:
        assert isinstance(chn_list, list), '传参错误'
        query_form = {"$add": []}
        for chn in chn_list:
            if target_event in ('bet', 'profit',):
                each_form = key.format(**{"param": 'groups_data._chn.data.{param}.data.'}).format(**{"param": chn})
                each_form = each_form.replace('%', '{')
                each_form = each_form.replace('#', '}')
                each_form = json.loads(each_form)
                query_form['$add'].append({'$ifNull': [each_form, 0]})
            else:
                each_form = key.format(**{"param": 'groups_data._chn.data.{param}.data.'}).format(**{"param": chn})
            query_form['$add'].append({'$ifNull': [each_form, 0]})
        group_by_query_dct['$group']['target'] = {'$sum': query_form}
    else:
        query_form = key.format(**{"param": 'data.'})
        if target_event in ('bet', 'profit',):
            query_form = query_form.replace('%', '{')
            query_form = query_form.replace('#', '}')
            query_form = json.loads(query_form)
    group_by_query_dct['$group']['target'] = {"$sum": query_form}
    return group_by_query_dct


def op_graph_report_handler(merchant_name, target_event, chn_list=None):
    """
    :param merchant_name: 商户名
    :param target_event: 事件对象
    :param chn_list: 渠道過濾
    :return:
    """
    assert merchant_name in settings.DWC_INDEX + settings.CP_INDEX
    report = {'graph_data': {}}
    condition = dict()
    if target_event in ('recharge', 'recharge_user'):
        condition['event_id'] = 'recharge'
    elif target_event in ('bind',):
        condition['event_id'] = 'bind_phone'
    elif target_event not in ('bet', 'profit'):
        condition['event_id'] = target_event
    group_by_query_dct = _get_graph_report_mongodb_group_by_query_dct(target_event, chn_list=chn_list)
    for key, start_delta, end_delta in (('today', 0, 0), ('yesterday', 1, 1),
                                        ('last_3', 3, 1), ('last_week', 7, 1),):
        report['graph_data'][key] = []
        day = datetime.combine(date.today(), time.min) - timedelta(days=start_delta)
        day_end = datetime.combine(date.today(), time.min) + timedelta(days=1 - end_delta)
        condition['base_time'] = {'$gte': day, '$lt': day_end}
        event_data = MONGODB[merchant_name].hour.aggregate([
            {'$match': condition},
            group_by_query_dct,
            {'$sort': {'_id': 1}}
        ])
        target = 0
        for item in event_data:
            target += item['target'] / (start_delta - end_delta + 1)
            report['graph_data'][key].append(target)
    return report


def op_report_handler(interval_type, base_time, last_window, event_name, event_rule, index):
    """
    :param interval_type: 报表时间单位
    :param base_time: 报表时间
    :param last_window: 时间段偏移值
    :param event_name: 报表名
    :param event_rule: 报表配置
    :param index: 商户索引名
    :return: None
    """
    start_time, end_time = get_interval_end_pair(interval_type, base_time, last_window)
    collection = '_'.join(['op', event_name, 'report'])
    report_template = get_report_template(start_time, interval_type)
    report_template.update(
        UserReportCreator.create_user_report(start_time=start_time, end_time=end_time,
                                             event_rule=event_rule, index=index)
    )
    insert_or_update(report_template, database=index, collection=collection)


def op_group_by_report_handler(interval_type, base_time, last_window, event_name, event_rule, index,
                               disable_global_aggregate=None):
    """
    :param interval_type: 报表时间单位
    :param base_time: 报表时间
    :param last_window: 时间段偏移值
    :param event_name: 报表名
    :param event_rule: 报表配置
    :param index: 商户索引名
    :param disable_global_aggregate: 是否关闭全局聚合
    :return: None
    """
    start_time, end_time = get_interval_end_pair(interval_type, base_time, last_window)
    collection = '_'.join(['op', event_name, 'report'])
    if not disable_global_aggregate:
        report_template = get_report_template(start_time, interval_type)
        report_template.update(
            UserReportCreator.create_user_report(start_time=start_time, end_time=end_time,
                                                 event_rule=event_rule, index=index)
        )
        report_template.update({event_rule.get('group_by').replace('.keyword', ''): 'all'})
        insert_or_update(report_template, database=index, collection=collection)
    recharge_reports = UserReportCreator.create_user_report(
        start_time=start_time, end_time=end_time, event_rule=event_rule, index=index, to_group=True
    )
    for report in recharge_reports['list']:
        report_id = '-'.join([report[event_rule.get('group_by').replace('.keyword', '')],
                              str(start_time).split(' ')[0], interval_type.value])
        report_template = get_report_template(start_time, interval_type, custom_report_id=report_id)
        report_template.update(report)
        insert_or_update(report_template, database=index, collection=collection)
